﻿using LungSoundWizard.ViewModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LungSoundWizard.Classes
{
    public class ReferenceSnippets : ObservableBase
    {
        ReferenceSnippet[] _snippets = new ReferenceSnippet[0];
        public ReferenceSnippet[] Snippets
        {
            get { return _snippets; }
            set { SetProperty(ref _snippets, value); }
        }

        double[] _average = new double[0];
        public double[] Average
        {
            get { return _average; }
            set { SetProperty(ref _average, value); }
        }

        double[] _stDev = new double[0];
        public double[] StDev
        {
            get { return _stDev; }
            set { SetProperty(ref _stDev, value); }
        }

        double[] _stDevNeg = new double[0];
        public double[] StDevNeg
        {
            get { return _stDevNeg; }
            set { SetProperty(ref _stDevNeg, value); }
        }

        public void RemoveSnippet(ReferenceSnippet snippet)
        {
            ReferenceSnippet[] newArray = new ReferenceSnippet[Snippets.Length];

            bool snippetFound = false;
            int snippetFoundCount = 0;
            for (int i = 0; i < Snippets.Length; i++)
            {
                if (Snippets[i] == snippet)
                {
                    snippetFound = true;
                    snippetFoundCount++;
                }
                else if (i < newArray.Length)
                {
                    if (snippetFound)
                    {
                        newArray[i - snippetFoundCount] = Snippets[i];
                    }
                    else
                    {
                        newArray[i] = Snippets[i];
                    }
                }
                else
                {
                    break;
                }
            }

            Array.Resize(ref newArray, Snippets.Length - snippetFoundCount);

            if (snippetFound)
            {
                Snippets = newArray;
            }
        }

        public void AddSnippet(ReferenceSnippet snippet)
        {
            ReferenceSnippet[] oldArray = Snippets;

            ReferenceSnippet[] newArray = new ReferenceSnippet[Snippets.Length + 1];
            Array.Copy(Snippets, newArray, Snippets.Length);

            newArray[newArray.Length - 1] = snippet;

            Snippets = newArray;

            RecalcAverage();
        }


        public void RecalcAverage()
        {
            if (Snippets.Length > 0)
            {
                double[] sum = new double[Snippets[0].AvgFft.Length];
                double[] sum2 = new double[Snippets[0].AvgFft.Length];
                Average = new double[Snippets[0].AvgFft.Length];
                StDev = new double[Snippets[0].AvgFft.Length];
                StDevNeg = new double[Snippets[0].AvgFft.Length];

                for (int i = 0; i < Snippets.Length; i++)
                {
                    for (int f = 0; f < Average.Length; f++)
                    {
                        sum[f] += Snippets[i].AvgFft[f];
                    }
                }

                for (int f = 0; f < Average.Length; f++)
                {
                    Average[f] = sum[f] / Snippets.Length;
                }

                // Now do stdev
                for (int j = 0; j < Snippets.Length; j++)
                {
                    for (int f = 0; f < Average.Length; f++)
                    {
                        sum2[f] += Math.Pow(Snippets[j].AvgFft[f] - Average[f], 2);
                    }
                }

                for (int f = 0; f < Average.Length; f++)
                {
                    StDev[f] = Math.Sqrt(sum2[f] / (Snippets.Length - 1));
                    StDevNeg[f] = -StDev[f];
                }
            }
        }
    }
}
